﻿package com.yy.bitmap {
    import flash.events.*;
    import flash.utils.*;
    import flash.display.*;
    import com.fminutes.vinciBase.*;
    import flash.geom.*;

    public class BitmapManager {

        public static const A:int = 1;
        public static const B:int = 3;
        public static const C:int = 4;

        public static var minFps:int = 10;
        public static var percentage:Number = 0.5;
        public static var appStage:Stage;
        private static var _instance:BitmapManager;
        public static var smoothing:Boolean = false;

        private var limitTime:int = 100;
        private var drawTime:int = 20;
        private var _compDic:Dictionary;
        private var _referenceCount:Dictionary;
        private var _destroyTimeDic:Dictionary;
        private var _destroyGettimeDic:Dictionary;
        private var _compFnDic:Dictionary;
        private var _frameCompFnDic:Dictionary;
        private var _sourceMCDic:Dictionary;
        private var _frameCompDic:Dictionary;
        private var _frameNumDic:Dictionary;
        private var _ing1:Array;
        private var _ing1_1:Array;
        private var _ing2:Array;
        private var _ing2_1:Array;
        private var _ing3:Array;
        private var _ing3_1:Array;
        private var _ing4:Array;
        private var _ing4_1:Array;
        private var _ING:Array;
        private var _frameTime:int = 0;
        private var _drawEnding:Boolean = true;
        private var _enterFrameTime:int = 0;
        private var _drawOver:Boolean = false;

        public function BitmapManager(){
            appStage = App.appStage;
            this.limitTime = (1000 / minFps);
            this.drawTime = ((1000 / appStage.frameRate) * percentage);
            this._frameTime = getTimer();
            this._compDic = new Dictionary();
            this._referenceCount = new Dictionary();
            this._destroyTimeDic = new Dictionary();
            this._destroyGettimeDic = new Dictionary();
            this._compFnDic = new Dictionary();
            this._frameCompFnDic = new Dictionary();
            this._sourceMCDic = new Dictionary();
            this._frameCompDic = new Dictionary();
            this._frameNumDic = new Dictionary();
            this._ing1 = [];
            this._ing2 = [];
            this._ing3 = [];
            this._ing4 = [];
            this._ing1_1 = [];
            this._ing2_1 = [];
            this._ing3_1 = [];
            this._ing4_1 = [];
            this._ING = [this._ing1, this._ing2, this._ing3, this._ing4, this._ing1_1, this._ing2_1, this._ing3_1, this._ing4_1];
            appStage.addEventListener(Event.ENTER_FRAME, this.enterFrameHandler);
        }
        private static function getInstance():BitmapManager{
            if (_instance == null){
                _instance = new (BitmapManager)();
            };
            return (_instance);
        }
        public static function draw(_arg1:Class, _arg2:Function, _arg3:Function=null, _arg4:int=3, _arg5:int=10000):void{
            var _local6:BitmapManager = getInstance();
            _local6.draw(_arg1, _arg2, _arg3, _arg4, _arg5);
        }
        public static function destroy(_arg1:*):void{
            var _local2:BitmapManager = getInstance();
            _local2.destroy(_arg1);
        }

        private function enterFrameHandler(_arg1:Event):void{
            this.drawHandler();
            this.destroyHandler();
        }
        private function drawHandler():void{
            if (this._drawEnding){
                return;
            };
            this._enterFrameTime = getTimer();
            var _local1:int = (this._enterFrameTime - this._frameTime);
            this._frameTime = this._enterFrameTime;
            if (_local1 > this.limitTime){
                return;
            };
            this._drawOver = false;
            this.frameHandler(this._ing1, this._ing1_1);
            this.frameHandler(this._ing2, this._ing2_1);
            this.frameHandler(this._ing3, this._ing3_1);
            this.frameHandler(this._ing4, this._ing4_1);
            this.allHandler(this._ing1_1);
            this.allHandler(this._ing2_1);
            this.allHandler(this._ing3_1);
            this.allHandler(this._ing4_1);
            this._drawEnding = this.clearNullForArrar(this._ING);
        }
        private function destroyHandler():void{
            var _local2:*;
            var _local3:int;
            var _local4:int;
            var _local5:Array;
            var _local6:int;
            var _local1:int = getTimer();
            for (_local2 in this._referenceCount) {
                if (this._referenceCount[_local2] <= 0){
                    _local3 = this._destroyGettimeDic[_local2];
                    _local4 = this._destroyTimeDic[_local2];
                    if ((_local1 - _local3) > _local4){
                        if (this._compDic[_local2] != null){
                            _local5 = this._compDic[_local2];
                            _local6 = 0;
                            while (_local6 < _local5.length) {
                                (_local5[_local6][0] as BitmapData).dispose();
                                _local6++;
                            };
                            delete this._compDic[_local2];
                            delete this._referenceCount[_local2];
                            delete this._destroyTimeDic[_local2];
                            delete this._destroyGettimeDic[_local2];
                            delete this._sourceMCDic[_local2];
                            delete this._frameCompDic[_local2];
                        };
                    };
                };
            };
        }
        private function frameHandler(_arg1:Array, _arg2:Array):void{
            var _local5:*;
            var _local6:DisplayObject;
            var _local7:BitmapData;
            var _local8:Array;
            var _local9:int;
            var _local10:MovieClip;
            if (this._drawOver){
                return;
            };
            var _local3:int = _arg1.length;
            var _local4:int;
            while (_local4 < _local3) {
                _local5 = _arg1[_local4];
                if (_local5 == null){
                } else {
                    _local6 = (this._sourceMCDic[_local5] as DisplayObject);
                    if (_local6 == null){
                        _arg1[_local4] = null;
                    } else {
                        if (this._frameCompDic[_local5] == null){
                            this._frameCompDic[_local5] = [];
                        };
                        _local9 = 0;
                        if ((_local6 is MovieClip)){
                            _local10 = (_local6 as MovieClip);
                            _local8 = this.drawMovieClip(_local10);
                            _local9 = _local10.totalFrames;
                            _local10.nextFrame();
                        } else {
                            _local8 = this.drawMovieClip(_local6);
                            _local9 = 1;
                        };
                        this._frameNumDic[_local5] = _local9;
                        this._frameCompDic[_local5].push(_local8);
                        this.callFn(this._frameCompFnDic[_local5], this._frameCompDic[_local5], this._frameNumDic[_local5]);
                        delete this._frameCompFnDic[_local5];
                        _arg2.push(_arg1[_local4]);
                        _arg1[_local4] = null;
                        if ((getTimer() - this._enterFrameTime) > this.drawTime){
                            this._drawOver = true;
                            return;
                        };
                    };
                };
                _local4++;
            };
        }
        private function allHandler(_arg1:Array):void{
            var _local4:*;
            var _local5:DisplayObject;
            var _local6:MovieClip;
            var _local7:int;
            var _local8:int;
            var _local9:int;
            if (this._drawOver){
                return;
            };
            var _local2:int = _arg1.length;
            var _local3:int;
            while (_local3 < _local2) {
                _local4 = _arg1[_local3];
                if (_local4 == null){
                } else {
                    _local5 = (this._sourceMCDic[_local4] as DisplayObject);
                    if (_local5 == null){
                        _arg1[_local3] = null;
                    } else {
                        if ((_local5 is MovieClip)){
                            _local6 = (_local5 as MovieClip);
                            _local7 = _local6.currentFrame;
                            _local8 = _local6.totalFrames;
                            _local9 = _local7;
                            while (_local9 <= _local8) {
                                this._frameCompDic[_local4].push(this.drawMovieClip(_local6));
                                _local6.nextFrame();
                                if (((((getTimer() - this._enterFrameTime) > this.drawTime)) && (!((_local9 == _local8))))){
                                    this._drawOver = true;
                                    return;
                                };
                                _local9++;
                            };
                        };
                        this._compDic[_local4] = this._frameCompDic[_local4];
                        this.callFn(this._compFnDic[_local4], this._compDic[_local4], this._frameNumDic[_local4]);
                        delete this._compFnDic[_local4];
                        delete this._sourceMCDic[_local4];
                        _arg1[_local3] = null;
                        if ((getTimer() - this._enterFrameTime) > this.drawTime){
                            this._drawOver = true;
                            return;
                        };
                    };
                };
                _local3++;
            };
        }
        private function drawMovieClip(_arg1:DisplayObject):Array{
            var _local2:Rectangle = _arg1.getBounds(_arg1);
            _local2.width = (_local2.width + 3);
            var _local3:BitmapData = new BitmapData(_local2.width, _local2.height, true, 0xFFFFFF);
            _local3.draw(_arg1, new Matrix(1, 0, 0, 1, -(Math.floor(_local2.x)), -(Math.floor(_local2.y))));
            return ([_local3, new Point(Math.floor(_local2.x), Math.floor(_local2.y))]);
        }
        private function clearNullForArrar(_arg1:Array):Boolean{
            var _local5:Array;
            var _local2:int = _arg1.length;
            var _local3:int;
            var _local4:Boolean;
            _local3 = 0;
            while (_local3 < _local2) {
                _local5 = (_arg1[_local3] as Array);
                this.deleteArrayItemForValue(_local5, null);
                if (_local5.length > 0){
                    _local4 = false;
                };
                _local3++;
            };
            return (_local4);
        }
        private function deleteArrayItemForValue(_arg1:Array, _arg2:Object):Array{
            var _local5:Object;
            var _local3:int = _arg1.length;
            var _local4:int;
            var _local6:int;
            while (_local6 < _local3) {
                if (_arg1[_local6] != _arg2){
                    _local5 = _arg1[_local4];
                    _arg1[_local4] = _arg1[_local6];
                    _arg1[_local6] = _local5;
                    _local4 = (_local4 + 1);
                };
                _local6++;
            };
            _arg1.length = _local4;
            return (_arg1);
        }
        private function callFn(_arg1:Array, _arg2:Object, _arg3:Object):void{
            var _local6:Function;
            if (_arg1 == null){
                return;
            };
            var _local4:int = _arg1.length;
            var _local5:int;
            while (_local5 < _local4) {
                _local6 = (_arg1[_local5] as Function);
                if (_local6 != null){
                    _local6(_arg2, _arg3);
                };
                _local5++;
            };
        }
        private function draw(_arg1:Class, _arg2:Function, _arg3:Function=null, _arg4:int=3, _arg5:int=1000):void{
            var _local6:Object;
            if (this._compDic[_arg1] != null){
                _arg2(this._frameCompDic[_arg1], this._frameNumDic[_arg1]);
                if (_arg3 != null){
                    _arg3(this._frameCompDic[_arg1], this._frameNumDic[_arg1]);
                };
                if (this._referenceCount[_arg1] == null){
                    this._referenceCount[_arg1] = 0;
                };
                this._referenceCount[_arg1] = (this._referenceCount[_arg1] + 1);
            } else {
                if (_arg3 != null){
                    if (this._frameCompDic[_arg1] != null){
                        _arg3(this._frameCompDic[_arg1], this._frameNumDic[_arg1]);
                    } else {
                        if (this._frameCompFnDic[_arg1] == null){
                            this._frameCompFnDic[_arg1] = [];
                        };
                        (this._frameCompFnDic[_arg1] as Array).push(_arg3);
                    };
                };
                if (this._compFnDic[_arg1] == null){
                    this._compFnDic[_arg1] = [];
                };
                (this._compFnDic[_arg1] as Array).push(_arg2);
                this._destroyTimeDic[_arg1] = _arg5;
                if (this._sourceMCDic[_arg1] == null){
                    _local6 = new (_arg1)();
                    if ((_local6 is MovieClip)){
                        (_local6 as MovieClip).stop();
                    };
                    this._sourceMCDic[_arg1] = _local6;
                    switch (_arg4){
                        case BitmapManager.A:
                            this._ing1.push(_arg1);
                            break;
                        case BitmapManager.B:
                            if (this._frameCompDic[_arg1] == null){
                                this._ing2.push(_arg1);
                            } else {
                                this._ing3.push(_arg1);
                            };
                            break;
                        case BitmapManager.C:
                            this._ing4.push(_arg1);
                            break;
                    };
                };
                this._drawEnding = false;
                if (this._referenceCount[_arg1] == null){
                    this._referenceCount[_arg1] = 0;
                };
                this._referenceCount[_arg1] = (this._referenceCount[_arg1] + 1);
            };
        }
        private function destroy(_arg1:*):void{
            if (this._referenceCount[_arg1] > 1){
                this._referenceCount[_arg1] = (this._referenceCount[_arg1] - 1);
            } else {
                if (this._referenceCount[_arg1] == 1){
                    this._referenceCount[_arg1] = (this._referenceCount[_arg1] - 1);
                    this._destroyGettimeDic[_arg1] = getTimer();
                };
            };
        }

    }
}//package com.fminutes.vinciBitmap 
